﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System;

#endregion

namespace ScrumTable.Common.Data
{
    /// <summary>
    /// Specifies the data type of a value.
    /// </summary>
    public enum DataType
    {
        /// <summary>
        /// Specifies that the current field contains a string without any formatting.
        /// A string represents a single line of content.
        /// </summary>
        String = 0,

        /// <summary>
        /// Specifies that the current field contains a string without any formatting.
        /// PlainText represents multiple line of content.
        /// </summary>
        PlainText,

        /// <summary>
        /// Specifies that the current field contains a string with HTML formatting.
        /// Html represents multiple line of content.
        /// </summary>
        Html,

        /// <summary>
        /// Specifies that the current field contains an Integer value (System.Int32).
        /// </summary>
        Integer,

        /// <summary>
        /// Specifies that the current field contains a Float value (System.Float).
        /// </summary>
        Float,

        /// <summary>
        /// Specifies that the current field contains a Double value (System.Double).
        /// </summary>
        Double,

        /// <summary>
        /// Specifies that the current field contains a DateTime value (System.DateTime).
        /// </summary>
        DateTime,

        /// <summary>
        /// Specifies that the current field contains a Boolean value (System.Boolean).
        /// </summary>
        Boolean
    }


    /// <summary>
    /// This class is used to convert a DataType instance into a .net framework
    /// type.
    /// </summary>
    public static class DataTypeConverter
    {
        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        #endregion

        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        /// <summary>
        /// Parses the given string and returns the corresponding
        /// DataType instance.
        /// </summary>
        /// <param name="type">Specifies the string representation of the data to parse.</param>
        public static DataType ParseDataType(string type)
        {
            return EnumUtil.TryParse(type, DataType.String);
        }

        /// <summary>
        /// Converts the given DataType instance into a .net framework type.
        /// </summary>
        /// <param name="type">Specifies the type to convert.</param>
        /// <returns>Returns the converted type.</returns>
        public static Type ToClassType(DataType type)
        {
            switch (type)
            {
                case DataType.PlainText:
                case DataType.Html:
                case DataType.String:
                    {
                        return typeof (string);
                    }
                case DataType.Integer:
                    {
                        return typeof (int);
                    }
                case DataType.Float:
                    {
                        return typeof (float);
                    }
                case DataType.Double:
                    {
                        return typeof(double);
                    }
                case DataType.DateTime:
                    {
                        return typeof (DateTime);
                    }
                case DataType.Boolean:
                    {
                        return typeof(bool);
                    }
                default:
                    {
                        throw new ArgumentOutOfRangeException("type");
                    }
            }
        }

        /// <summary>
        /// Converts the given DataType instance into a .net framework type.
        /// </summary>
        /// <param name="type">Specifies the type to convert.</param>
        /// <returns>Returns the converted type.</returns>
        public static DataType ToDataType(Type type)
        {
            DataType convertedType;

            if (!TryToDataType(type, out convertedType))
            {
                throw new ArgumentOutOfRangeException("type");
            }
            return convertedType;
        }

        /// <summary>
        /// Tries to convert the given .net framework type ont a DataType
        /// construct. The default return value is PlainText.
        /// </summary>
        /// <param name="type">Specifies the type to convert.</param>
        /// <param name="result">Contains the data of the result value.</param>
        /// <returns>Returns true if the conversation succeeded, otherwise false.</returns>
        public static bool TryToDataType(Type type, out DataType result)
        {
            type = Nullable.GetUnderlyingType(type) ?? type;

            if (type == typeof(string))
            {
                result = DataType.String;
                return true;
            }
            if (type == typeof(int))
            {
                result = DataType.Integer;
                return true;
            }
            if (type == typeof(double))
            {
                result = DataType.Double;
                return true;
            }
            if (type == typeof(DateTime))
            {
                result = DataType.DateTime;
                return true;
            }
            if (type == typeof(bool))
            {
                result = DataType.Boolean;
                return true;
            }

            result = DataType.PlainText;
            return false;
        }

        /// <summary>
        /// Tries to convert the given .net framework type ont a DataType
        /// construct. The default return value is PlainText.
        /// </summary>
        /// <param name="type">Specifies the type to convert.</param>
        /// <returns>Returns true if the conversation succeeded, otherwise false.</returns>
        public static DataType TryToDataType(Type type)
        {
            DataType dataType;
            TryToDataType(type, out dataType);
            return dataType;
        }

        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        #endregion
    }
}